import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:example/utils/common.dart';
import 'package:example/base/custom_widget.dart';
import 'package:example/config/color_config.dart';
import 'package:example/utils/file_ext.dart';
import 'package:example/utils/list_ext.dart';
import 'package:example/utils/user_handle_manager.dart';
import 'package:example/widget/my_image.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:marquee/marquee.dart';
import 'package:video_player/video_player.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

import '../data/repository/oss_repository.dart';
import 'dialog/image_picker_dialog.dart';

enum MediaType { image, video, custom }

enum MediaActionType { all, camera, photos }

typedef UploadMediaCustomItem = Function(
    UploadMediaController controller, int index, File? entity, String? url);

typedef UploadMediaCustomImageItem = Function(UploadMediaController controller,
    int index, AssetEntity? entity, String? url);

typedef UploadMediaCustomAddItem = Function(UploadMediaController controller);

typedef FileIconBuilder = Widget Function(
    UploadMediaController controller, int index, File? entity, String? url);

class UploadMedia extends CustomWidget<UploadMediaController> {
  final List<String>? allowedExtensions;
  final MediaType mediaType;
  final MediaActionType actionType;

  UploadMedia({
    Key? key,
    UploadMediaController? controller,
    List<File>? files, // 文件
    List<AssetEntity>? images, // 图片/视频
    List<String>? previewUrls,
    List<String>? urls,
    this.allowedExtensions,
    this.mediaType = MediaType.image,
    this.actionType = MediaActionType.all,
    bool defaultCamera = true,
    bool autoUpload = false,
    bool singleUpload = false,
    int max = 1,
    double? height,
    double? width,
    EdgeInsets? margin,
    EdgeInsets? padding,
    BorderRadius? borderRadius,
    Color? background,
    double? spacing,
    double? runSpacing,
    String? closeIconPath,
    double? closeIconWidth,
    double? closeIconHeight,
    double? closeIconSafePadding,
    BorderRadius? itemBorderRadius,
    double? itemWidth,
    double? itemHeight,
    Color? addItemBackground,
    String? addItemIconPath,
    String? addItemTitleStr,
    double? addItemIconWidth,
    double? addItemIconHeight,
    UploadMediaCustomAddItem? customAddItem,
    UploadMediaCustomItem? customItem,
    UploadMediaCustomImageItem? customImageItem,
    FileIconBuilder? fileIconBuilder,
    bool isPreview = false,
    bool? isDel,
    bool? isAdd,
    String? code,
    Function(int index, AssetEntity? file)? onPreviewImageTap,
    Function(int index, AssetEntity? file)? onDelImageTap,
    Function(List<AssetEntity> file)? onAddImageTap,
    Function(List<AssetEntity> file)? onUnAddImageTap,
    Function(int index, File? file)? onPreviewTap,
    Function(int index, File? file)? onDelTap,
    Function(List<File> file)? onAddTap,
    Function(List<File> file)? onUnAddTap,
    Function(int type)? onTap,
  }) : super(
      UploadMediaController(
        files: files,
        images: images,
        urls: urls,
        previewUrls: previewUrls,
        defaultCamera: defaultCamera,
        autoUpload: autoUpload,
        max: max,
        height: height,
        width: width,
        margin: margin,
        padding: padding,
        borderRadius: borderRadius,
        background: background,
        spacing: spacing,
        runSpacing: runSpacing,
        closeIconPath: closeIconPath,
        closeIconWidth: closeIconWidth,
        closeIconHeight: closeIconHeight,
        itemBorderRadius: itemBorderRadius,
        itemWidth: itemWidth,
        itemHeight: itemHeight,
        addItemBackground: addItemBackground,
        addItemIconPath: addItemIconPath,
        addItemTitleStr: addItemTitleStr,
        addItemIconWidth: addItemIconWidth,
        addItemIconHeight: addItemIconHeight,
        customAddItem: customAddItem,
        customItem: customItem,
        customImageItem: customImageItem,
        fileIconBuilder: fileIconBuilder,
        isDel: isDel,
        isAdd: isAdd,
        code: code,
        onPreviewImageTap: onPreviewImageTap,
        onDelImageTap: onDelImageTap,
        onAddImageTap: onAddImageTap,
        onUnAddImageTap: onUnAddImageTap,
        onPreviewTap: onPreviewTap,
        onDelTap: onDelTap,
        onAddTap: onAddTap,
        onUnAddTap: onUnAddTap,
        onTap: onTap,
        singleUpload: singleUpload
      ),
      key: key,
      externalController: controller) {
    assert(!(mediaType == MediaType.custom && allowedExtensions == null),
    "allowedExtensions 不能为null");

    if (controller != null) {
      if (controller.files.length < (files?.length ?? 0)) {
        controller.files = files ?? [];
      }
      if (controller.images.length < (images?.length ?? 0)) {
        controller.images = images ?? [];
      }
      if (controller.urls.length < (urls?.length ?? 0)) {
        controller.urls = urls ?? [];
      }
      if (controller.previewUrls.length < (previewUrls?.length ?? 0)) {
        controller.previewUrls = previewUrls ?? [];
      }
      if (controller.max == null || controller.max! < max) {
        controller.max = max;
      }
      controller.defaultCamera = controller.defaultCamera ?? defaultCamera;
      controller.autoUpload = controller.autoUpload ?? autoUpload;
      controller.height = controller.height ?? height;
      controller.width = controller.width ?? width;
      controller.margin = controller.margin ?? margin;
      controller.padding = controller.padding ?? padding;
      controller.borderRadius = controller.borderRadius ?? borderRadius;
      controller.background = controller.background ?? background;
      controller.spacing = controller.spacing ?? spacing;
      controller.runSpacing = controller.runSpacing ?? runSpacing;
      controller.closeIconPath = controller.closeIconPath ?? closeIconPath;
      controller.closeIconWidth = controller.closeIconWidth ?? closeIconWidth;
      controller.closeIconHeight =
          controller.closeIconHeight ?? closeIconHeight;
      controller.closeIconSafePadding =
          controller.closeIconSafePadding ?? closeIconSafePadding;
      controller.itemBorderRadius =
          controller.itemBorderRadius ?? itemBorderRadius;
      controller.itemWidth = controller.itemWidth ?? itemWidth;
      controller.itemHeight = controller.itemHeight ?? itemHeight;
      controller.addItemBackground =
          controller.addItemBackground ?? addItemBackground;
      controller.addItemIconPath =
          controller.addItemIconPath ?? addItemIconPath;
      controller.addItemTitleStr = controller.addItemTitleStr ?? addItemTitleStr;
      controller.addItemIconWidth =
          controller.addItemIconWidth ?? addItemIconWidth;
      controller.addItemIconHeight =
          controller.addItemIconHeight ?? addItemIconHeight;
      controller.customAddItem = controller.customAddItem ?? customAddItem;
      controller.customItem = controller.customItem ?? customItem;
      controller.customImageItem =
          controller.customImageItem ?? customImageItem;
      controller.fileIconBuilder =
          controller.fileIconBuilder ?? fileIconBuilder;
      controller.isDel = controller.isDel ?? isDel ?? !isPreview;
      controller.isAdd = controller.isAdd ?? isAdd ?? !isPreview;
      controller.code = controller.code ?? code;
      controller.onPreviewImageTap =
          controller.onPreviewImageTap ?? onPreviewImageTap;
      controller.onDelImageTap = controller.onDelImageTap ?? onDelImageTap;
      controller.onAddImageTap = controller.onAddImageTap ?? onAddImageTap;
      controller.onUnAddImageTap =
          controller.onUnAddImageTap ?? onUnAddImageTap;
      controller.onPreviewTap = controller.onPreviewTap ?? onPreviewTap;
      controller.onDelTap = controller.onDelTap ?? onDelTap;
      controller.onAddTap = controller.onAddTap ?? onAddTap;
      controller.onUnAddTap = controller.onUnAddTap ?? onUnAddTap;
      controller.onTap = controller.onTap ?? onTap;
      controller.singleUpload = controller.singleUpload ?? singleUpload;
    }
  }

  @override
  Widget initView(BuildContext context, UploadMediaController controller) {
    return Container(
      margin: controller.margin,
      padding: controller.padding,
      height: controller.height,
      width: controller.width,
      decoration: BoxDecoration(
        color: controller.background,
        borderRadius: controller.borderRadius,
      ),
      child: _mediaWidget(controller),
    );
  }

  _mediaWidget(UploadMediaController controller) {
    List<Widget> widgets = [];
    if (mediaType == MediaType.custom) {
      // 链接预览
      controller.previewUrls.forEachIndexed<String>((index, url) {
        widgets.add(controller.customImageItem == null
            ? _itemNetworkFile(controller, index, url)
            : controller.customItem?.call(controller, index, null, url));
      });
      // 文件列表
      controller.files.forEachIndexed<File>((index, entity) {
        widgets.add(controller.customImageItem == null
            ? _itemFile(controller, index, entity)
            : controller.customItem?.call(controller, index, entity, null));
      });
    } else if (mediaType == MediaType.video) {
      // 链接预览
      controller.previewUrls.forEachIndexed<String>((index, url) {
        widgets.add(controller.customImageItem == null
            ? _itemNetworkVideo(controller, index, url)
            : controller.customImageItem?.call(controller, index, null, url));
      });

      // 图片/视频列表
      controller.images.forEachIndexed<AssetEntity>((index, entity) {
        widgets.add(controller.customImageItem == null
            ? _itemImage(controller, index, entity)
            : controller.customImageItem
            ?.call(controller, index, entity, null));
      });
    } else {
      // 链接预览
      controller.previewUrls.forEachIndexed<String>((index, url) {
        widgets.add(controller.customImageItem == null
            ? _itemNetworkImage(controller, index, url)
            : controller.customImageItem?.call(controller, index, null, url));
      });

      // 图片/视频列表
      controller.images.forEachIndexed<AssetEntity>((index, entity) {
        widgets.add(controller.customImageItem == null
            ? _itemImage(controller, index, entity)
            : controller.customImageItem
            ?.call(controller, index, entity, null));
      });
    }

    // 添加按钮
    if (widgets.length < (controller.max ?? 1) && controller.isAdd == true) {
      widgets.add(controller.customAddItem == null
          ? _addMedia(controller)
          : controller.customAddItem?.call(controller));
    }
    return Wrap(
      spacing: controller.spacing ?? 0,
      runSpacing: controller.runSpacing ?? 0,
      children: widgets,
    );
  }

  /// 文件子项
  Widget _itemFile(UploadMediaController controller, int index, File entity) {
    double closeIconSafePadding =
    controller.isDel != true ? 0 : (controller.closeIconSafePadding ?? 0);
    return Stack(
      children: [
        Padding(
          padding: EdgeInsets.fromLTRB(
              0, closeIconSafePadding, closeIconSafePadding, 0),
          child: GestureDetector(
            onTap: () {
              controller.onTap?.call(0);
              // if (controller.isPreview == true) {
              //   // TODO 暂不支持预览文件
              // } else {
              FilePicker.platform
                  .pickFiles(
                  allowMultiple: false,
                  type: FileType.custom,
                  allowedExtensions: allowedExtensions,
                  onFileLoading: (state) {
                    switch (state) {
                      case FilePickerStatus.picking:
                        showLoading();
                        break;
                      case FilePickerStatus.done:
                        hideLoading();
                        break;
                    }
                  })
                  .then((value) {
                showLoading();
                List<String?>? paths =
                value?.paths.where((path) => _ignoreFile(path)).toList();
                List<File>? file = paths?.map((path) => File(path!)).toList();
                if (file != null) {
                  controller.uploadOss([file[0]], () {
                    File delFile = controller.files[index];
                    controller.delFileAt(index);
                    controller.addFile(index, file[0]);
                    controller.onUnAddTap?.call([delFile]);
                    controller.onAddTap?.call([file[0]]);
                  });
                }
                hideLoading();
              });
              // }
            },
            child: Container(
              height: controller.itemHeight,
              width: controller.itemWidth,
              decoration: BoxDecoration(
                border: Border.all(color: ColorConfig.FFD8D8D8, width: 0.5.w),
                borderRadius: controller.itemBorderRadius,
              ),
              child: controller.fileIconBuilder
                  ?.call(controller, index, entity, null) ??
                  _defaultFile(controller, entity.getFullFileName()),
            ),
          ),
        ),
        Visibility(
          visible: controller.isDel == true,
          child: Positioned(
            right: 0,
            child: GestureDetector(
              onTap: () {
                controller.onTap?.call(2);
                File file = controller.files[index];
                controller.delFileAt(index);
                controller.onDelTap?.call(index, file);
              },
              child: MyImage(
                path:
                controller.closeIconPath ?? "assets/svg/ic_upload_del.svg",
                width: controller.closeIconWidth ?? 15.w,
                height: controller.closeIconHeight ?? 15.w,
              ),
            ),
          ),
        ),
      ],
    );
  }

  /// 网络文件子项
  Widget _itemNetworkFile(
      UploadMediaController controller, int index, String url) {
    double closeIconSafePadding =
    controller.isDel != true ? 0 : (controller.closeIconSafePadding ?? 0);
    return Stack(
      children: [
        Padding(
          padding: EdgeInsets.fromLTRB(
              0, closeIconSafePadding, closeIconSafePadding, 0),
          child: GestureDetector(
            onTap: () {
              controller.onTap?.call(0);
              if (url.endsWith(".pdf")) {
                // previewPDF(url: url);
              }
            },
            child: Container(
              height: controller.itemHeight,
              width: controller.itemWidth,
              decoration: BoxDecoration(
                border: Border.all(color: ColorConfig.FFD8D8D8, width: 0.5.w),
                borderRadius: controller.itemBorderRadius,
              ),
              child: controller.fileIconBuilder
                  ?.call(controller, index, null, url) ??
                  _defaultFile(controller, url.split("/").last),
            ),
          ),
        ),
        Visibility(
          visible: controller.isDel == true,
          child: Positioned(
            right: 0,
            child: GestureDetector(
              onTap: () {
                controller.onTap?.call(2);
                controller.delPreviewFileAt(index);
                controller.onDelTap?.call(index, null);
              },
              child: MyImage(
                path:
                controller.closeIconPath ?? "assets/svg/ic_upload_del.svg",
                width: controller.closeIconWidth ?? 15.w,
                height: controller.closeIconHeight ?? 15.w,
              ),
            ),
          ),
        ),
      ],
    );
  }

  _defaultFile(UploadMediaController controller, String name) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        MyImage(
          path: "assets/svg/ic_file_excel.svg",
          width: 40.w,
          height: 40.w,
        ),
        SizedBox(
          width: controller.itemWidth,
          height: 20.w,
          child: Marquee(
            text: name,
            pauseAfterRound: const Duration(seconds: 1),
            blankSpace: 20.0,
            startPadding: 0,
            style: TextStyle(
              color: ColorConfig.text_gray,
              fontSize: 12.sp,
            ),
          ),
        ),
      ],
    );
  }

  /// 图片子项
  Widget _itemImage(
      UploadMediaController controller, int index, AssetEntity entity) {
    double closeIconSafePadding =
    controller.isDel != true ? 0 : (controller.closeIconSafePadding ?? 0);
    return Stack(
      children: [
        Padding(
          padding: EdgeInsets.fromLTRB(
              0, closeIconSafePadding, closeIconSafePadding, 0),
          child: GestureDetector(
            onTap: () {
              controller.onTap?.call(0);
              // if (controller.isPreview == true) {
              //   previewPhotos(previewAssets: controller.images).then((value) =>
              //       controller.onPreviewImageTap
              //           ?.call(index, controller.images[index]));
              // } else {
              int max = (controller.max ?? 0) - controller.previewUrls.length;
              if (max < 1) {
                max = 1;
              }
              List<AssetEntity> oldList = controller.images.toList();
              UserHandleManager().openPhotos(
                selectedAssets: controller.images,
                maxCount: max,
                type: controller.getImageType(mediaType),
              ).then((file) {
                if (file != null) {
                  List<AssetEntity> diffAddFile =
                  controller.diffAddImage(file, oldList);
                  List<AssetEntity> diffDelFile =
                  controller.diffDelImage(file, oldList);
                  controller.uploadImageOss(diffAddFile, mediaType, () {
                    controller.delImages(diffDelFile);
                    controller.addImageAll(diffAddFile);
                    controller.onUnAddImageTap?.call(diffDelFile);
                    controller.onAddImageTap?.call(diffAddFile);
                  });
                }
              });
              // }
            },
            child: ClipRRect(
              borderRadius: controller.itemBorderRadius ?? BorderRadius.zero,
              child: Image(
                image: AssetEntityImageProvider(entity, isOriginal: false),
                height: controller.itemHeight,
                width: controller.itemWidth,
                fit: BoxFit.cover,
              ),
            ),
          ),
        ),
        Visibility(
          visible: controller.isDel == true,
          child: Positioned(
            right: 0,
            child: GestureDetector(
              onTap: () {
                controller.onTap?.call(2);
                AssetEntity file = controller.images[index];
                controller.delImageAt(index);
                controller.onDelImageTap?.call(index, file);
              },
              child: MyImage(
                path:
                controller.closeIconPath ?? "assets/svg/ic_upload_del.svg",
                width: controller.closeIconWidth ?? 15.w,
                height: controller.closeIconHeight ?? 15.w,
              ),
            ),
          ),
        ),
      ],
    );
  }

  /// 网络图片子项
  Widget _itemNetworkImage(
      UploadMediaController controller, int index, String url) {
    double closeIconSafePadding =
    controller.isDel != true ? 0 : (controller.closeIconSafePadding ?? 0);
    return Stack(
      children: [
        Padding(
          padding: EdgeInsets.fromLTRB(
              0, closeIconSafePadding, closeIconSafePadding, 0),
          child: GestureDetector(
            onTap: () {
              controller.onTap?.call(0);
              previewNetworkImages(
                  urls: controller.previewUrls, selected: index)
                  ?.then((value) =>
                  controller.onPreviewImageTap?.call(index, null));
            },
            child: MyImage(
              path: url,
              height: controller.itemHeight,
              width: controller.itemWidth,
              borderRadius: controller.itemBorderRadius,
              fit: BoxFit.cover,
            ),
          ),
        ),
        Visibility(
          visible: controller.isDel == true,
          child: Positioned(
            right: 0,
            child: GestureDetector(
              onTap: () {
                controller.onTap?.call(2);
                controller.delPreviewImageAt(index);
                controller.onDelImageTap?.call(index, null);
              },
              child: MyImage(
                path:
                controller.closeIconPath ?? "assets/svg/ic_upload_del.svg",
                width: controller.closeIconWidth ?? 15.w,
                height: controller.closeIconHeight ?? 15.w,
              ),
            ),
          ),
        ),
      ],
    );
  }

  /// 网络视频子项
  Widget _itemNetworkVideo(
      UploadMediaController controller, int index, String url) {
    double closeIconSafePadding =
    controller.isDel != true ? 0 : (controller.closeIconSafePadding ?? 0);
    return Stack(
      children: [
        Padding(
          padding: EdgeInsets.fromLTRB(
              0, closeIconSafePadding, closeIconSafePadding, 0),
          child: GestureDetector(
            onTap: () {
              controller.onTap?.call(0);
              // previewNetworkVideos(
              //     urls: controller.previewUrls, selected: index)
              //     ?.then((value) =>
              //     controller.onPreviewImageTap?.call(index, null));
            },
            child: GetBuilder<UploadMediaController>(
              id: controller.idVideo,
              init: controller,
              global: false,
              builder: (controller) {
                return SizedBox(
                  height: controller.itemHeight,
                  width: controller.itemWidth,
                  child: VideoPlayer(
                    controller.videoController[index],
                  ),
                );
              },
            ),
          ),
        ),
        Visibility(
          visible: controller.isDel == true,
          child: Positioned(
            right: 0,
            child: GestureDetector(
              onTap: () {
                controller.onTap?.call(2);
                controller.delPreviewImageAt(index);
                controller.onDelImageTap?.call(index, null);
              },
              child: MyImage(
                path:
                controller.closeIconPath ?? "assets/svg/ic_upload_del.svg",
                width: controller.closeIconWidth ?? 15.w,
                height: controller.closeIconHeight ?? 15.w,
              ),
            ),
          ),
        ),
      ],
    );
  }

  /// 新增图片/文件
  _addMedia(UploadMediaController controller) {
    return Padding(
      padding: EdgeInsets.fromLTRB(0, controller.closeIconSafePadding ?? 0,
          controller.closeIconSafePadding ?? 0, 0),
      child: GestureDetector(
        onTap: () {
          controller.onTap?.call(1);
          int max = (controller.max ?? 0) - controller.previewUrls.length;
          if (max < 1) {
            max = 1;
          }
          if (MediaType.custom == mediaType) {
            FilePicker.platform
                .pickFiles(
                allowMultiple: max > 1,
                type: FileType.custom,
                allowedExtensions: allowedExtensions,
                onFileLoading: (state) {
                  switch (state) {
                    case FilePickerStatus.picking:
                      showLoading();
                      break;
                    case FilePickerStatus.done:
                      hideLoading();
                      break;
                  }
                })
                .then((value) {
              List<String?>? paths =
              value?.paths.where((path) => _ignoreFile(path)).toList();
              int maxLength = max - controller.files.length;
              if (maxLength < (paths?.length ?? 0)) {
                paths = paths?.sublist(0, maxLength);
              }
              List<File>? file = paths?.map((path) => File(path!)).toList();
              if (file != null) {
                controller.uploadOss(file, () {
                  controller.addFileAll(file);
                  controller.onAddTap?.call(file);
                });
              }
            });
          } else {
            List<AssetEntity> oldList = controller.images.toList();
            showImagePickerDialog(
                selectedAssets: controller.images,
                type: controller.getImageType(mediaType),
                actionType: actionType,
                defaultCamera: controller.defaultCamera ?? true,
                maxCount: max,
                confirm: (type, file) {
                  if (file != null) {
                    if (type == 1) {
                      controller.uploadImageOss(file, mediaType, () {
                        controller.addImageAll(file);
                        controller.onAddImageTap?.call(file);
                      });
                    } else if (type == 2) {
                      List<AssetEntity> diffAddFile =
                      controller.diffAddImage(file, oldList);
                      List<AssetEntity> diffDelFile =
                      controller.diffDelImage(file, oldList);
                      controller.uploadImageOss(diffAddFile, mediaType, () {
                        controller.delImages(diffDelFile);
                        controller.addImageAll(diffAddFile);
                        controller.onUnAddImageTap?.call(diffDelFile);
                        controller.onAddImageTap?.call(diffAddFile);
                      });
                    }
                  }
                });
          }
        },
        child: Container(
          height: controller.itemHeight,
          width: controller.itemWidth,
          decoration: BoxDecoration(
            color: controller.addItemBackground ?? ColorConfig.FFEEEEEE,
            borderRadius: controller.itemBorderRadius,
          ),
          alignment: Alignment.center,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              MyImage(
                path: controller.addItemIconPath ?? "assets/svg/ic_upload_add.svg",
                width: controller.addItemIconWidth ?? 18.w,
                height: controller.addItemIconHeight ?? 18.w,
              ),
              // SizedBox(height: isNotEmptyOrNull(controller.addItemTitleStr) ? 5.w : 0,),
              // Text(controller.addItemTitleStr ?? '',
              //   style: TextStyle(color: ColorConfig.text_gray, fontSize: 12.sp),)
            ],
          ),
        ),
      ),
    );
  }

  bool _ignoreFile(String? path) {
    return path != null &&
        (allowedExtensions?.any((e) => path.endsWith("." + e)) ?? false);
  }
}

class UploadMediaController extends GetxController {
  final ossRepository = Get.find<OssRepository>();
  List<File> files = [];
  List<AssetEntity> images = [];
  List<String> previewUrls = [];
  List<String> urls = [];
  List<VideoPlayerController> videoController = [];
  bool? defaultCamera;
  bool? autoUpload;
  int? max;
  double? height;
  double? width;
  EdgeInsets? margin;
  EdgeInsets? padding;
  BorderRadius? borderRadius;
  Color? background;
  double? spacing;
  double? runSpacing;
  String? closeIconPath;
  double? closeIconWidth;
  double? closeIconHeight;
  double? closeIconSafePadding;
  BorderRadius? itemBorderRadius;
  double? itemWidth;
  double? itemHeight;
  Color? addItemBackground;
  String? addItemIconPath;
  String? addItemTitleStr;
  double? addItemIconWidth;
  double? addItemIconHeight;
  UploadMediaCustomAddItem? customAddItem;
  UploadMediaCustomItem? customItem;
  UploadMediaCustomImageItem? customImageItem;
  FileIconBuilder? fileIconBuilder;
  bool? isDel;
  bool? isAdd;
  String? code;
  Function(int index, AssetEntity? file)? onPreviewImageTap;
  Function(int index, AssetEntity? file)? onDelImageTap;
  Function(List<AssetEntity> file)? onAddImageTap;
  Function(List<AssetEntity> file)? onUnAddImageTap;
  Function(int index, File? file)? onPreviewTap;
  Function(int index, File? file)? onDelTap;
  Function(List<File> file)? onAddTap;
  Function(List<File> file)? onUnAddTap;
  Function(int type)? onTap; // 0 查看 1 添加 2 删除
  bool? singleUpload;
  final String idVideo = "idVideo";

  UploadMediaController({
    List<File>? files,
    List<AssetEntity>? images,
    List<String>? urls,
    List<String>? previewUrls,
    this.autoUpload,
    this.defaultCamera,
    this.max,
    this.height,
    this.width,
    this.margin,
    this.padding,
    this.borderRadius,
    this.background,
    this.spacing,
    this.runSpacing,
    this.closeIconPath,
    this.closeIconWidth,
    this.closeIconHeight,
    this.itemBorderRadius,
    this.itemWidth,
    this.itemHeight,
    this.addItemBackground,
    this.addItemIconPath,
    this.addItemTitleStr,
    this.addItemIconWidth,
    this.addItemIconHeight,
    this.customAddItem,
    this.customItem,
    this.customImageItem,
    this.fileIconBuilder,
    this.isAdd,
    this.isDel,
    this.code,
    this.onPreviewImageTap,
    this.onDelImageTap,
    this.onAddImageTap,
    this.onUnAddImageTap,
    this.onPreviewTap,
    this.onDelTap,
    this.onAddTap,
    this.onUnAddTap,
    this.onTap,
    this.singleUpload
  })  : images = images ?? [],
        files = files ?? [],
        urls = urls ?? [],
        previewUrls = previewUrls ?? [];

  /// url
  void updateUrls(List<String>? urls) {
    previewUrls = urls ?? [];
    if (true) {
      videoController.clear();
      var iterable = previewUrls.map<VideoPlayerController>(
              (url) => VideoPlayerController.network(url)
            ..initialize().then((_) {
              update([idVideo]);
            }));
      if (iterable.isNotEmpty == true) {
        videoController.addAll(iterable);
      }
    }
    update();
  }

  void removeUrl(int index) {
    urls.removeAt(index);
  }

  /// ############ 文件 操作 ############
  void addFile(int index, File? file) {
    if (file != null) {
      files.insert(index, file);
      update();
    }
  }

  void addFileAll(List<File>? file) {
    if (file != null) {
      files.addAll(file);
      update();
    }
  }

  void delPreviewFileAt(int index) {
    if (previewUrls.length > index) {
      previewUrls.removeAt(index);
    }
    update();
  }

  void delFileAt(int index) {
    files.removeAt(index);
    if (urls.length > index) {
      urls.removeAt(index);
    }
    update();
  }

  void uploadOss(List<File>? data, VoidCallback fun) async {
    if (data?.isEmpty == true) {
      fun.call();
      return;
    }
    if(singleUpload == true && data?.length == 1){
      ossRepository.uploadAvatar(file: (data?.first ?? File('')),isLoading: true).then((value){
        if(value.data?.url!=null){
          urls.add(value.data?.url ?? '');
          fun.call();
        }
      });
    }else{
      ossRepository.uploadOss(files: files, isLoading: true).then((value) {
        if(value.data?.url!=null){
          urls.addAll(value.data?.url??[]);
          fun.call();
        }
      });
    }
  }

  /// ############ 图片/视频 操作 ############
  RequestType getImageType(MediaType mediaType) {
    if (mediaType == MediaType.image) {
      return RequestType.image;
    } else {
      return RequestType.video;
    }
  }

  void addImageAll(List<AssetEntity>? file) {
    if (file != null) {
      images.addAll(file);
      update();
    }
  }

  void updateImage(List<AssetEntity>? file) {
    images = file ?? [];
    update();
  }

  void delPreviewImageAt(int index) {
    if (previewUrls.length > index) {
      previewUrls.removeAt(index);
    }
    update();
  }

  void delImageAt(int index) {
    images.removeAt(index);
    if (urls.length > index) {
      urls.removeAt(index);
    }
    update();
  }

  void delImages(List<AssetEntity>? file) {
    file?.forEach((element) {
      int index = 0;
      images.removeWhere((item) {
        bool remove = item.id == element.id;
        if (remove && urls.length > index) {
          urls.removeAt(index);
        }
        index++;
        return remove;
      });
    });
    update();
  }

  /// 比较差异文件 新增
  List<AssetEntity> diffAddImage(
      List<AssetEntity>? file, List<AssetEntity> oldList) {
    List<AssetEntity> list = [];
    file?.forEach((element) {
      Iterable iterable = oldList.where((old) => old.id == element.id);
      if (iterable.isEmpty) {
        list.add(element);
      }
    });
    return list;
  }

  /// 比较差异文件 删除
  List<AssetEntity> diffDelImage(
      List<AssetEntity>? file, List<AssetEntity> oldList) {
    List<AssetEntity> list = [];
    for (var element in oldList) {
      Iterable? iterable = file?.where((old) => old.id == element.id);
      if (iterable?.isNotEmpty != true) {
        list.add(element);
      }
    }
    return list;
  }

  void uploadImageOss(
      List<AssetEntity>? data, MediaType type, VoidCallback fun) async {
    if (data?.isEmpty == true) {
      fun.call();
      return;
    }
    List<File> files = await data.getFiles(isCompress: type == MediaType.image);
    if (files.isEmpty == true) {
      fun.call();
      return;
    }
    if(singleUpload == true && files.length == 1){
      ossRepository.uploadAvatar(file: (files.first),isLoading: true).then((value){
        if(value.data?.url!=null){
          urls.add(value.data?.url ?? '');
          fun.call();
        }
      });
    }else{
      ossRepository.uploadOss(files: files, isLoading: true).then((value) {
        if(value.data?.url!=null){
          urls.addAll(value.data?.url??[]);
          fun.call();
        }
      });
    }

  }
}
